
/*
定义多画面视频播放器
功能描述：

    显示相关功能成员变量：
        1.画面保存数组
        2.焦点索引，标明第几个画面被选中
        3.最大化标记，标明是否有画面被最大化，如果有，则肯定是焦点画面
        4.区域id，div的id，该div是所有画面所在的那个div 的id
        4.整个区域的宽高，
        5.单个画面的宽高
    显示相关功能：
        1.显示多个画面：1,4,9,16等
            1.1获取总区域的宽高，保存并设置单个画面的宽高
            1.2创建播放器对象，如果对象存在一部分，则补足
            1.3设置每个画面的位置，宽高，是否显示
            1.4
        2.双击单个画面，画面最大化
        3.双击最大化画面，还原
        4.单击单个画面，显示焦点


    指令方面成员变量：
        当前视频种类：实时视频，视频回放，对讲，监听
    指令方面功能：
        1.发送实时视频指令
        2.发送视频回放指令
        3.发送视频停止指令

*/
!(function(){

    var shplayers = function(obj){



        this.id = '';//定义当前对象的载体控件id


        this.serverIp = '';//服务器ip
        this.port = 0;//端口号
        this.simNo = '';//通讯号
        this.plateNo = '';//车牌号

        this.firstFlg = true;//定义第一次标记，标明是否第一次初始化


        this.channels = [];//定义所有已经定义的数组
        this.playerNum = 0;//定义当前显示的画面数
        this.totalWidth = 400;//定义当前总的区域宽
        this.totalHeight = 260;//定义当前总的区域高
        this.playerWidth = 150;
        this.playerHeight = 100;
        this.emptySize = 3;//定义单个播放器外侧需要保留的控件，用于绘制焦点线
        this.focalPointSize = 2;//定义焦点的宽度
        this.minWidth = 300;//定义最小宽度，
        this.minHeight = 200;//定义最小高度



        this.focalPointIndex = -1;//定义焦点索引
        this.maxSizeFlg = false;//最大化画面标记，当前是否有画面最大化,默认没有,如果有最大化，那么焦点索引即最大化的画面的控件索引

        this.applayNums =[1,4,6,8,9,16];//支持的最大画面数



        this.debug = false;//定义是否调试，如果为true，则输出调试信息

        // this.stopCallback = null;//定义停止按钮点击后的回调方法
        
        if(!this.isUndefined(obj)){
            this.init(obj);
        }
            
    };


    shplayers.prototype = {
        //格式化数据
        format:function(obj){
            return this.standardization(obj,this);
        },
        //初始化，用于多次调用
        init:function(obj){
            //如果画面数不同，则开始初始化
            //格式化数据
            if (!this.format(obj)) {
                this.error("初始化多画面播放器参数错误");
                return false;
            }
            
            //初始化基本数据
            if (!this.initData()) {
                this.error("初始化多画面播放器基本数据错误");
                return false;
            }
            //初始化播放器
            if (!this.initPlayers(true)) {
                this.error("初始化多画面播放器失败");
                return false;
            }

            this.out("初始化多画面播放器成功");


            // this.out(this);
            return true;
        },

        /*
        初始化数据，并对数据进行校正
        */
        initData:function(){
            var me = this;

            // this.out(this.applayNums);
            // this.out(this.applayNums.indexOf(this.playerNum));
            //初始化画面数，使其合法
            if(this.playerNum < 1)
                this.playerNum = 1;
            if(this.playerNum > 16)
                this.playerNum = 16;
            //初始化画面数
            if(this.applayNums.indexOf(this.playerNum) < 0){
                var nowNum = this.playerNum;
                var index = 0;
                var temp = 20;
                
                $.each(this.applayNums,function(i,num){
                    if(Math.abs(num - nowNum) <= temp){
                        //差值小于等于默认差值，替换
                        temp = Math.abs(num - nowNum);
                        index = i;
                    }
                });
                if(nowNum > me.applayNums[index])
                    index ++;
                this.playerNum = this.applayNums[index];
            }
            // this.out(this.playerNum);
            
            //初始化最大化标记:
            this.maxSizeFlg = false;
            // this.focalPointIndex = -1;

            //初始化控件区域
            this.out("初始化时对象数 = "+this.channels.length);
            this.out("画面数 = "+this.playerNum);

            var html = $("#"+this.id).html();
            if(html != ""){
                // $("#"+this.id).html("");
                // $("#"+this.id).empty();
            }


            return true;
        },

        /*
        初始化多画面播放器
            initFlg 为true表示需要初始化
            initFlg为false表示不需要初始化通道信息
        */
        initPlayers:function(initFlg){
            try {
                this.out("开始初始化多个播放器对象");
                if(!this.initSizes()){
                    this.error("初始化多画面播放器尺寸大小失败");
                    return false;
                }

                if(!this.initObjs(initFlg)){
                    this.error("初始化多画面播放器对象失败");
                    return false;
                }

                // this.out(this.channels);
                this.out("初始化多个播放器对象成功");
                return true;
            } catch (error) {
                this.error('初始化多画面播放器方法失败：'+error);
                return false;
            }
        },

        /*
        初始化方法1-1:
            初始化所有的size信息
            
        */
        initSizes: function () {
            var parentDivTemp = $("#" + this.id);
            if(this.isUndefined(parentDivTemp))
                return false;
            //初始化总区域宽高
            this.totalWidth = parseInt(parentDivTemp.css("width"));
            if(this.totalWidth < this.minWidth)
                this.totalWidth = this.minWidth;
            this.totalHeight = parseInt(parentDivTemp.css("height"));
            if(this.totalHeight < this.minHeight)
                this.totalHeight = this.minHeight;
            //画面个数最少为1个
            if (this.playerNum < 1)
                this.playerNum = 1;

            //初始化单个画面的宽高
            var oneLineNum = Math.floor(Math.sqrt(this.playerNum));//单行或者单列的数量
            this.playerWidth = parseInt(this.totalWidth/oneLineNum) - this.emptySize*2;;//单个画面的宽度
            this.playerHeight = parseInt(this.totalHeight/oneLineNum) - this.emptySize*2;//单个画面的高度 

            return true;
        },

        /*
        初始化1-2：
            初始化播放器对象
                1.如果存在对象数量不足，则补齐，如果够，则不添加
                2.设置需要显示的画面的信息
                3.设置不需要显示的画面的信息
            initFlg 为true表示需要初始化
            initFlg为false表示不需要初始化通道信息
        */
        initObjs:function(initFlg){
            try {
                var me = this;
                var parentDivTemp = $("#" + me.id);

                if(me.isUndefined(parentDivTemp))
                    return false;

                me.out("开始创建。。。。。。。");
                // me.out("创建前，对象数量 = "+me.channels.length+" 个 , 当前显示画面数="+me.playerNum);
                //如果对象数量不足，则补齐
                if(me.channels.length < me.playerNum){
                    for (var i = me.channels.length; i < me.playerNum; i++) {
                        var idTemp = me.id + i;
                        me.out(idTemp);
                        var html = '<div id="' + idTemp + '" style="width:200px;height:120px;position:absolute;background-color:darkgray;"></div>';
                        parentDivTemp.append(html);
                        // me.out("parentDivTemp");
                        // me.out(parentDivTemp);
                        me.channels[i] = me.getShplayerObj(idTemp,i);;//获取对象
                        $("#"+idTemp).css({'border-style':'solid','border-width':(me.focalPointSize+'px'),'border-color':'#A9A9A9'});
                    }
                }
                // me.out("创建后，对象数量 = "+me.channels.length+" 个 , 当前显示画面数="+me.playerNum);

                // this.out("改变后的值：simNo = "+this.simNo + " , plateNo = "+this.plateNo); 
                //初始化状态
                $.each(me.channels,function(j,shplayerTemp){
                    if(j<me.playerNum){
                        // me.out(me.getPlayerSizeByIndex(j,me.playerNum));
                        if(!me.initPlayerStatus2(shplayerTemp,j,true,me.playerNum)){
                            me.error("初始化第"+(j+1)+"个画面的状态错误");
                            return false;
                        }else{
                            //初始化状态
                            if(initFlg){
                                var obj = {
                                    serverIp: me.serverIp,
                                    port: me.port,
                                    simNo: me.simNo,
                                    channel: (j + 1),
                                    plateNo: me.plateNo,
                                };
                                // me.out("重置基本信息.")
                                // me.out(obj);
                                shplayerTemp.format(obj);
                                // me.out(shplayerTemp);
                                if(!me.firstFlg){
                                    shplayerTemp.setNewVideoUrl(shplayerTemp.initUrl());
                                }
                            }

                            shplayerTemp.showChannelMsg("",initFlg);
                            // 
                        }
                    }else{
                        shplayerTemp.videoPause();
                        if(!me.initPlayerStatus2(shplayerTemp,j,false,me.playerNum)){
                            me.error("初始化第"+(j+1)+"个画面的状态错误");
                            return false;
                        }
                    }
                });
                return true;
            } catch (error) {
                this.error("创建播放器失败："+error);
                return false;
            }
        },
        /*
        获取播放器对象
        */
        getShplayerObj: function (divId,index) {
            // var idName = this.id + index;
            var obj = {
                parent:this,
                playerDiv: divId,
                serverIp: this.serverIp,
                port: this.port,
                simNo: this.simNo,
                channel: (index + 1),
                plateNo: this.plateNo,
                stopBtnCallback: this.stopCallbackFun,
                maxScreenCallback:this.maxScreenCallbackFun,
                mouseClickCallback:this.mouseClickCallbackFun,
            };
            var shplayerTemp = new shplayer(obj);
            // this.out(shplayerTemp);
            return shplayerTemp;
        },

        /*
        初始化播放器的状态信息
        */
        initPlayerStatus2:function (shplayerTemp,index,showFlg,playerNum,bigsizeFlg){
            var me = this;
            // var idTemp = me.id+index;
            var idTemp = shplayerTemp.playerDiv;
            var divTemp = $("#"+idTemp);
            if (me.isUndefined(divTemp))
                return false;
            if(showFlg){
                var objSizeTemp = me.getPlayerSizeByIndex(index,playerNum);
                if(!me.isUndefined(objSizeTemp)){
                    // me.out(objSizeTemp);
                    var leftTemp = objSizeTemp.xTemp * objSizeTemp.playerWidthTemp ;//横向位置为横向距离单位*单个播放器宽度+位置偏移+me.emptySize
                    var topTemp = objSizeTemp.yTemp * objSizeTemp.playerHeightTemp ;//纵向位置，同上+ me.emptySize
                    var widthTemp = objSizeTemp.playerWidthTemp - me.emptySize;
                    var heightTemp = objSizeTemp.playerHeightTemp - me.emptySize;

                    divTemp.css("position", "absolute");
                    divTemp.css("display", "block");
                    divTemp.css("top", topTemp);
                    divTemp.css("left", leftTemp);
                    divTemp.css("width", widthTemp);
                    divTemp.css("height", heightTemp);


                    if(playerNum ==1){
                        // console.log("最大化");
                        divTemp.css("z-index",100);
                    }else{
                        divTemp.css("z-index",0);
                    }

                    if(!this.isUndefined(shplayerTemp)){
                        // shplayerTemp.resetSize();
                        me.out("resize");
                    }
                }
            }else{
                //隐藏控件，不需要计算，直接设置和隐藏,并且设置播放器暂停
                divTemp.css("display","none");
                divTemp.css("top",(me.totalHeight+"px"));
                divTemp.css("left","1px");
                // divTemp.css("width","1px");
                // divTemp.css("height","1px");
            }
            return true;
        },
        /*
        通过索引和画面数，获取位置大小信息
            1.首先根据情况计算获取x轴y轴的距离单位
            2.然后计算获取单位画面的大小
        */
        getPlayerSizeByIndex:function(index,playerNum){
            var me = this;

            var objSizeTemp = {};
            var xTemp = 0;//定义x轴距离单位
            var yTemp = 0;//定义y轴距离单位
            var playerWidthTemp = 0;//定义单画面宽度,包含边框预留空间
            var playerHeightTemp = 0;//定义单画面高度，包含边框预留空间

            switch(playerNum){
                //单画面
                case 1:
                    playerWidthTemp = me.totalWidth;
                    playerHeightTemp = me.totalHeight;
                break;
                //6画面和8画面
                case 6:
                case 8:
                    var oneLineNum = Math.floor(playerNum/2);//定义单行的画面数，最大的数量
                    if(index == 0){
                        playerWidthTemp = Math.floor(me.totalWidth*(oneLineNum-1)/oneLineNum);
                        playerHeightTemp = Math.floor(me.totalHeight*(oneLineNum-1)/oneLineNum);
                    }else{
                        xTemp = index > oneLineNum ? (playerNum - 1 - index) : (oneLineNum -1);
                        yTemp = index <= oneLineNum ? (index -1 ) : (oneLineNum -1);
                        playerWidthTemp = Math.floor(me.totalWidth/oneLineNum);
                        playerHeightTemp = Math.floor(me.totalHeight/oneLineNum);
                    }
                break;
                //其他画面数，暂定为4,9,16
                case 4:
                case 9:
                case 16:
                    var oneLineNum = Math.floor(Math.sqrt(playerNum));//定义单行的画面数，最大的数量
                    xTemp = Math.floor(index % oneLineNum);
                    yTemp = Math.floor(index / oneLineNum);
                    playerWidthTemp = Math.floor(me.totalWidth/oneLineNum);
                    playerHeightTemp = Math.floor(me.totalHeight/oneLineNum);
                break;
            }

            objSizeTemp.index = index;
            objSizeTemp.xTemp = xTemp;
            objSizeTemp.yTemp = yTemp;
            objSizeTemp.playerWidthTemp = playerWidthTemp;
            objSizeTemp.playerHeightTemp = playerHeightTemp;

            return objSizeTemp;
        },


        /*
        
        设置所有视频的声音
        */
        setAllVolume:function(volume){
            var me = this;
            me.out("set all volumes");
            if(me.channels.length > 0){
                for(var i=0 ; i<me.channels.length ; i++){
                    if(i < me.playerNum){
                        var shplayerTemp = me.channels[i];
                        if(!me.isUndefined(shplayerTemp) && !me.isUndefined(shplayerTemp.ckplayer)){
                            var ckplayer = shplayerTemp.ckplayer;
                            if(typeof(ckplayer.V.changeVolume) == "function"){
                                shplayerTemp.ckplayer.changeVolume(volume);
                                // me.out("set volumes , num :"+i);
                            }
                            // ckplayer.videoMute();
                        }

                    }
                }
            }
        },


        /*
        停止所有视频的播放
            设置所有的的对象的播放
        */
        stopAllVideos:function(){
            var me = this;
            me.out("stop all");
            if(me.channels.length > 0){
                for(var i=0 ; i<me.channels.length ; i++){
                    var shplayerTemp = me.channels[i];
                    if (!me.isUndefined(shplayerTemp)) {
                        shplayerTemp.videoPause();
                        me.out("stop num :"+i);
                    }
                }
            }
        },
        /*
        开始播放所有视频
            只播放显示的视频
        */
        playAllVideos:function(){
            var me = this;
            me.out("play all");
            // me.out(me.channels);
            if(me.channels.length > 0){
                for(var i=0 ; i<me.channels.length ; i++){
                    if(i < me.playerNum){
                        var shplayerTemp = me.channels[i];
                        if(!me.isUndefined(shplayerTemp)){
                            shplayerTemp.videoPlay();
                            me.out("play num :"+i);
                        }

                    }else{
                        me.out("break play");
                        break;
                    }
                }
            }
        },

        /*
            播放指定通道的视频
                通道号从1开始，
        */
        playOneVideo:function(channelId){
            if(channelId <1 || channelId > this.channels.length)
                return;
            var shplayerTemp = this.channels[channelId-1];
            if(!this.isUndefined(shplayerTemp)){
                shplayerTemp.videoPlay();
            }
        },

        /*
        点击停止按钮的回调方法
            本方法由shplayer对象调用，所以方法中的this为shplayer对象
        */
        stopCallbackFun:function(){
            this.out("停止按钮回调方法");
            this.out(this);
        },

        /*
        双击最大化回调方法
            本方法由shplayer对象调用，所以方法中的this为shplayer对象
            1.遍历所有对象
            2.如果当前对象不是焦点，则判断最大化标记，如果为true，则显示对象，如果为false，则隐藏对象
            3.如果当前对象是焦点，判断最大化标记，如果为true，则调用方法还原，如果为false，则调用方法最大化
        */
        maxScreenCallbackFun:function(){
            var parent = this.parent;
            var divIdTemp = this.playerDiv;
            if (this.isUndefined(divIdTemp))
                return;

            var changeFlg = false;//定义标记，保存当前是否改变某个对象的最大化状态
            $.each(parent.channels, function (i, shplayerTemp2) {
                // parent.out("循环开始："+i+"playerNum="+parent.playerNum);
                if (i < parent.playerNum) {
                    var divIdTemp2 = shplayerTemp2.playerDiv;
                    // parent.out(divIdTemp2);
                    if (divIdTemp == divIdTemp2) {
                        //当前为焦点
                        if(parent.maxSizeFlg){
                            //当前是最大化
                            parent.initPlayerStatus2(shplayerTemp2,i,true,parent.playerNum);//还原
                            // parent.out(i+"焦点还原");
                        }else{
                            //非最大化
                            parent.initPlayerStatus2(shplayerTemp2,0,true,1);//最大化
                            // parent.out(i+"焦点最大化");
                        }
                        changeFlg = true;
                    } else {
                        //非焦点
                        $("#"+divIdTemp2).css("z-index",0);
                        if(parent.maxSizeFlg){
                            //当前有最大化画面，则需要还原，并且显示非焦点画面
                            // $("#"+divIdTemp2).css("display","block");
                            
                            // parent.out(i+"非焦点显示");
                        }else{
                            //当前没有最大化画面，则需要隐藏非焦点
                            // $("#"+divIdTemp2).css("display","none");
                            // parent.out(i+"非焦点隐藏");
                        }
                        // me.setOnePlayerFocalPointStatus(divTemp2, false);
                    }
                }
            });
            //改变最大化状态
            if(changeFlg){
                parent.maxSizeFlg = parent.maxSizeFlg?false:true;
            }
            // parent.out("最大化标记"+parent.maxSizeFlg);
            // this.out("最大化回调方法");
            // this.out(this);
        },

        /*
        单击单个播放器后的回调方法
            本方法由shplayer对象调用，所以方法中的this为shplayer对象
        */
        mouseClickCallbackFun: function (index) {
            var playersTemp = this.parent;
            if (this.isUndefined(playersTemp))
                return;
            if(index != playersTemp.focalPointIndex){
                //索引不相等
                playersTemp.focalPointIndex = index;
                //设置焦点状态
                playersTemp.setFocalPointPlayerStatus(this);
            }
            // this.out(this);
            this.out("当前焦点：" + this.playerDiv);
        },
        /*
        设置当前播放器为选中的焦点状态
        */
        setFocalPointPlayerStatus:function(shplayerTemp){
            var me = this;
            var divTemp = shplayerTemp.playerDiv;
            // me.out(divTemp);
            if(me.isUndefined(divTemp))
                return ;

            $.each(me.channels,function(i,shplayerTemp2){
                // me.out("循环开始："+i+"playerNum="+me.playerNum);
                if(i<me.playerNum){
                    var divTemp2 = shplayerTemp2.playerDiv;
                    if(divTemp == divTemp2){
                        //设置焦点
                        me.setOnePlayerFocalPointStatus(divTemp2,true);
                    }else{
                        //取消焦点
                        me.setOnePlayerFocalPointStatus(divTemp2,false);
                    }
                }
            });
        },
        //设置单个播放器的焦点状态
        setOnePlayerFocalPointStatus:function(divTemp,showFlg){
            // this.out(objTemp);
            if(this.isUndefined(divTemp))
                return;
            var objTemp = $("#"+divTemp);
            if(showFlg){
                objTemp.css({'border-style':'solid','border-width':(this.focalPointSize+'px'),'border-color':'#0F0'});
            }else{
                objTemp.css({'border-style':'solid','border-width':(this.focalPointSize+'px'),'border-color':'#A9A9A9'});
            }
        },

        /*
        显示单个播放器的命令执行结果
        */
        showOnePlayerCmdMsg:function(channelId,msg){
            if(channelId <1 || channelId > this.channels.length)
                return;
            var shplayerTemp = this.channels[channelId-1];
            if(!this.isUndefined(shplayerTemp)){
                // this.out("命令执行结果信息：" + msg);
                shplayerTemp.showCmdMsg(msg);
            }
        },

        /*
        显示单个播放器的通道信息
        */
        showOnePlayerChannelMsg:function(channelId,msg,setFlg){
            if (channelId < 1 || channelId > this.channels.length)
                return;
            var shplayerTemp = this.channels[channelId - 1];
            if (!this.isUndefined(shplayerTemp)) {
                shplayerTemp.showChannelMsg(msg,setFlg);
            }
        },

        //设置单个播放器的地址
        setOnePlayerUrl:function(channelId,url){
            if (channelId < 1 || channelId > this.channels.length)
                return;
            var shplayerTemp = this.channels[channelId - 1];
            if (!this.isUndefined(shplayerTemp)) {
                shplayerTemp.setNewVideoUrl(url,false);//参数为地址和不自动播放
            }
        },


        /*
        通过通道号获取播放器对象，
            通道号下标从1开始，即通道1对应对象0
        */
        getPlayerByChannel:function(channelId){
            if(this.channels.length <= channelId || channelId < 1){
                return null;
            }
            var shplayerTemp = this.channels[channelId-1];
            if(this.isUndefined(shplayerTemp))
                return null;
            else 
                return shplayerTemp;
        },







        /*
        设置所有播放器的地址
        */
       setPlayersUrl:function(url,autoplayFlg){
        //    this.out("设置地址");
           if(url == "")
                return;
           $.each(this.channels,function(i,shplayerTemp){
               shplayerTemp.setNewVideoUrl(url,autoplayFlg);
           });
       },



        //公用方法,从f读取数据,并标准化输入到t
        //
        standardization:function(f,t){
            try {
                var temp ;
                for(temp in f){
                    var type = typeof(t[temp]);
                    switch(type){
                        case 'number':
                            t[temp] = parseFloat(f[temp]);
                        break;
                        default:
                            t[temp] = f[temp];
                        break;
                    }
                }
                // this.out("standardization success");
                return true;
            } catch (error) {
                this.error("标准化输入数据错误："+error);
                return false;
            }
        },

        //公共方法,输出信息
        //
        out:function(msg){
            if(this.debug)
                console.log(msg);
        },

        //公共方法,输出错误
        //
        error:function(error){
            console.error(error);
        },

        //公共方法,判断是否为undefined

        isUndefined:function(value){
            try {
                if (value == 'undefined' || value == undefined || value == null) {
                    return true;
                }
            } catch(event) {
                this.out(event);
            }
            return false;
        }
    };

    window.shplayers = shplayers;
})();